#include "EventCollection.h"

#include "EventFileDriver.h"
#include "EventHash.h"
#include "EventObject.h"

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>

struct _EventCollection
{
	EventObject  parent_instance;
	EventHash   *collections;
	EventString *event_path;
};

static void
event_collection_finalize(EventCollection *self)
{
	HashItem_p  h_item;
	EventTable *e_table;
	/* 所有事件表全部写入文件当中 */
	event_hash_iter_reset(self->collections);
	h_item = event_hash_iter_get(self->collections);
	while (h_item) {
		e_table = EVENT_TABLE(event_hash_item_get_value(h_item));
		event_file_driver_dump(EVENT_FILE_DRIVER(e_table));
		h_item = event_hash_iter_get(self->collections);
	}
	event_object_unref(self->collections);
	event_object_unref(self->event_path);
}

EventCollection *
event_collection_new(void)
{
	EventCollection *object = MALLOC_NEW(EventCollection);

	event_object_init(EVENT_OBJECT(object));
	event_object_set_finalize(object, FINALIZE(event_collection_finalize));

	object->collections = event_hash_new(EVENT_HASH_MODEL_NUMBER);
	object->event_path  = NULL;

	return object;
}

void
event_collection_set_path(EventCollection *self, EventString *event_path)
{
	return_if_fail(self != NULL || event_path != NULL,
		       event_collection_set_path);
	self->event_path = EO_REF(event_path, EventString);
}

EventTable *
event_collection_load_table(EventCollection *self, euint32 group_id,
			    bool will_create_new)
{
	static char  group_fp_name[15];
	struct stat  stat_info;
	EventString *event_table_path;
	EventTable  *e_table = NULL;
	int	     status;

	return_val_if_fail(self != NULL, event_collection_load_table, NULL);
	return_val_if_fail(self->event_path != NULL,
			   event_collection_load_table, NULL);

	e_table = EVENT_TABLE(
		event_hash_get(self->collections, EPTR((euint64)group_id)));
	if (e_table)
		return e_table;
	/* 检查文件夹是否存在 */
	sprintf(group_fp_name, "%07u", group_id);
	event_table_path =
		event_string_copy_append(self->event_path, group_fp_name);
	status = stat(ES_GET(self->event_path), &stat_info);
	if (status == -1 && errno == ENOENT)
		status = mkdir(ES_GET(self->event_path), 0755);
	if (status == -1) {
		perror("mkdir");
		goto return_with_error;
	}

	e_table = event_table_new();
	event_file_driver_set_file(EVENT_FILE_DRIVER(e_table),
				   ES_GET(event_table_path));
	if (will_create_new) {
		event_file_driver_set_file_not_exist_throw(
			EVENT_FILE_DRIVER(e_table), false);
	}
	status = event_file_driver_loader(EVENT_FILE_DRIVER(e_table));
	if (status == EVENT_FILE_DRIVER_SUCCESS) {
		event_hash_set(self->collections, EPTR((euint64)group_id),
			       e_table, event_object_unref);
	} else {
		event_object_unref(e_table);
		e_table = NULL;
	}
return_with_error:
	event_object_unref(event_table_path);
	return e_table;
}

void
event_collection_remove_table(EventCollection *self, euint32 group_id)
{
	static char  group_fp_name[15];
	struct stat  stat_info;
	EventString *event_table_path;

	return_if_fail(self != NULL, event_collection_load_table);
	return_if_fail(self->event_path != NULL, event_collection_load_table);

	if (!event_hash_verify_exist(self->collections,
				     EPTR((euint64)group_id))) {
		return;
	}
	event_hash_remove(self->collections, EPTR((euint64)group_id));
	/* 检查文件夹是否存在 */
	sprintf(group_fp_name, "%07u", group_id);
	event_table_path =
		event_string_copy_append(self->event_path, group_fp_name);
	if (stat(ES_GET(self->event_path), &stat_info) != 0) {
		perror("stat");
		goto return_with_error;
	}
	if (!S_ISREG(stat_info.st_mode))
		goto return_with_error;
	if (remove(ES_GET(event_table_path)))
		perror("remove");

return_with_error:
	event_object_unref(event_table_path);
}
